home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / astrsys / strings.asm < prev    next >
Encoding:
Assembly Source File  |  1989-09-25  |  25.3 KB  |  509 lines

  1.                             PAGE    ,132
  2.                             TITLE   String manipulation -- LARGE MEM (FAR)
  3.                             NAME    StrPackL
  4.  
  5. ; Use this file in any way that pleases you.
  6.  
  7.                             DOSSEG
  8.                             .MODEL  LARGE
  9.  
  10. .XLIST
  11. XchgSeg         MACRO   Seg1,Seg2
  12.                 Push    Seg1        ; Save the Segment register
  13.                 Push    Seg2        ; Save the Segment register
  14.                 Pop     Seg1        ; Put Segment here
  15.                 Pop     Seg2        ; The same for the first
  16.                 ENDM
  17. .LIST
  18.  
  19.  
  20. .DATA?
  21. TempW       DW      ?       ; Temporary Word size VAR
  22. TempW2      DW      ?       ; Another temporary word if needed
  23. TempB       DB      ?       ; Temporary Byte
  24.  
  25.  
  26.  
  27. .CODE
  28.  
  29. PUBLIC Length, Append, Concat, Extract,
  30. PUBLIC Split, LowerCase, UpperCase, Proper
  31. PUBLIC Trim, Checksum, Compare
  32.  
  33.  
  34. Length          Proc
  35. ;-----------------------------------------------------------------------------;
  36. ;   Returns the length of an asciiz string.                                   ;
  37. ;   INPUT:                                                                    ;
  38. ;      DS:SI  = Address of ASCIIZ string                                      ;
  39. ;   OUTPUT:                                                                   ;
  40. ;      AX = Length of string (Not including the NULL char at end              ;
  41. ;-----------------------------------------------------------------------------;
  42.                 Push    Di          ;
  43.                 Push    Cx          ; Save them
  44.                 Push    Es          ;
  45.                                     ;
  46.                 Xor     Cx,Cx       ; Clear to 0
  47.                 Not     Cx          ; And flip the bits
  48.                 Cld                 ;
  49.                 Mov     Di,Si       ;
  50.                 Push    Ds          ;
  51.                 Pop     Es          ;
  52.                 Mov     Al,0        ; Search
  53.                 Repnz   Scasb       ; Scan for the 0
  54.                 Not     Cx          ; Flip the bits back
  55.                 Mov     Ax,Cx       ; Put count Here
  56.                 Dec     Ax          ; And take one out -- do not include 0
  57.                                     ;
  58.                 Pop     Es          ;
  59.                 Pop     Cx          ; Get the old Cx
  60.                 Pop     Di          ; Get the ols si
  61.                 Ret                 ; And exit
  62. Length          Endp
  63.  
  64.  
  65.  
  66. Append          Proc
  67. ;-----------------------------------------------------------------------------;
  68. ; Appends Second string onto the first string in memory.                      ;
  69. ; INPUT:                                                                      ;
  70. ;      DS:SI = Address of First string.                                       ;
  71. ;      ES:DI = Address of Second string (one to be appedned                   ;
  72. ; OUTPUT:                                                                     ;
  73. ;      Nothing changed except first string is now Firststring+Secondstring    ;
  74. ;-----------------------------------------------------------------------------;
  75.                 Push    Ax          ; Save all the registers Used
  76.                 Push    Cx          ;
  77.                 Push    Si          ;
  78.                 Push    Di          ;
  79.                 Pushf               ; And the flags
  80.                                     ;
  81.                 Call    Length      ; Get the length of first string
  82.                 Add     Si,Ax       ; Add to get to end of first
  83.                 Xchg    Si,Di       ; Switch to
  84.                 XchgSeg Ds,Es       ; Exchange these segment registers
  85.                 Call    Length      ; Get the length of the second string
  86.                 Mov     Cx,Ax       ; Count
  87.                 Inc     Cx          ; Snag the ASCIIZ byte also
  88.                 Cld                 ; Up
  89.                 Rep     Movsb       ; Transfer
  90.                                     ;
  91.                 Popf                ; Pop everything used
  92.                 Pop     Di          ;
  93.                 Pop     Si          ;
  94.                 Pop     Cx          ;
  95.                 Pop     Ax          ;
  96.                 Ret                 ; And return
  97. Append          Endp                ;
  98.  
  99.  
  100. Concat          Proc
  101. ;-----------------------------------------------------------------------------;
  102. ; Works like Append except neither of the two orugunal strings are touched,   ;
  103. ; but the result is placed in another location all together (C := A+B)        ;
  104. ; INPUT:                                                                      ;
  105. ;     DS:SI = Address of First String                                         ;
  106. ;     DS:BX = Address of Second String                                        ;
  107. ;     ES:DI = Address to place (First String + Second String)                 ;
  108. ; OUTPUT:                                                                     ;
  109. ;     AX = Length of resulting string                                         ;
  110. ;-----------------------------------------------------------------------------;
  111.                 Push    Bx          ;
  112.                 Push    Cx          ;
  113.                 Push    Dx          ;
  114.                 Push    Si          ;
  115.                 Push    Di          ;
  116.                                     ;
  117.                 Cld                 ; Dest is ES:DI
  118.                                     ; Get some string lengths
  119.                 Call    Length      ; String 1
  120.                 Mov     Cx,Ax       ; Length of string 1 in CX
  121.                 Xchg    Bx,Si       ;
  122.                 Call    Length      ;
  123.                 Xchg    Bx,Si       ;
  124.                 Mov     Dx,Ax       ; Length of String 2 in DX
  125.                 Add     Ax,Cx       ; Get resulting length
  126.                 Mov     TempW,Ax    ; Save it for temp
  127.                                     ; Now,
  128.                 Rep     Movsb       ; Transfer part one
  129.                 Xchg    Dx,Cx       ; Switch
  130.                 Xchg    Bx,Si       ; Switch
  131.                 Inc     Cx          ; Include the ASCIIZ NULL
  132.                 Rep     Movsb       ; Move this
  133.                                     ; We are done
  134.                 Pop     Di          ;
  135.                 Pop     Si          ;
  136.                 Pop     Dx          ;
  137.                 Pop     Cx          ;
  138.                 Pop     Bx          ;
  139.                 Mov     Ax,TempW    ; Get the resulting count
  140.                 Ret                 ; And return
  141. Concat          Endp
  142.  
  143.  
  144. Extract         Proc
  145. ;-----------------------------------------------------------------------------;
  146. ; EXtracts a number of chars from a given string and puts in dest.            ;
  147. ; INPUT                                                                       ;
  148. ;     DS:SI = The address of string to be extracted from (source)             ;
  149. ;     ES:DI = Destination address of the new string                           ;
  150. ;     AX = Number of chars to extract                                         ;
  151. ; OUTPUT                                                                      ;
  152. ;     ES:DI = address of first char of new string.                            ;
  153. ;     everything else is actually unchanged.                                  ;
  154. ;-----------------------------------------------------------------------------;
  155.                 Push    Ax          ;
  156.                 Push    Cx          ;
  157.                 Push    Si          ;
  158.                                     ;
  159.                 Mov     Cx,Ax       ; Put this here
  160.                 Add     Si,Ax       ; Add offset
  161.                 Mov     Al,0        ;
  162.                 Cld                 ;
  163.                 Rep     Movsb       ; Move it -- HA and bingo
  164.                 Stosb               ; Save an ASCIIZ char
  165.                                     ;
  166.                 Pop     Si          ;
  167.                 Pop     Cx          ;
  168.                 Pop     Ax          ;
  169.                 Ret                 ;
  170. Extract         Endp
  171.  
  172.  
  173. Split           Proc
  174. ;-----------------------------------------------------------------------------;
  175. ; Splits a given ASCIIZ string into 2 distinct ASCIIZ string.                 ;
  176. ; INPUT                                                                       ;
  177. ;     DS:SI = Address of string to be split.                                  ;
  178. ;     BX    = Offset into DS:SI where the start of split occurs.              ;
  179. ;     ES:DI = OFfset of the second half of DS:SI (split) is to be placed.     ;
  180. ; OUTPUT                                                                      ;
  181. ;     ES:DI = Address of string that came from string one.                    ;
  182. ;     AX = New Length of string that was DS:SI                                ;
  183. ;     BX = Length of the string that is found in ES:DI                        ;
  184. ; Thus...                                                                     ;
  185. ;      "The green roof on the lawn",0 split at r of roof                      ;
  186. ;  BECOMES...                                                                 ;
  187. ;      "The green ",0        (DS:SI)  [New Length in AX]    AND               ;
  188. ;      "roof on the lawn",0  (ES:DI)  [New Length in BX]                      ;
  189. ;-----------------------------------------------------------------------------;
  190.                 Push    Cx          ;
  191.                 Push    Dx          ;
  192.                 Push    Si          ;
  193.                 Push    Di          ;
  194.                 Push    Bp          ;
  195.                 Cld                 ;
  196.                                     ;
  197.                 Push    Si          ;
  198.                 Call    Length      ; Get the length
  199.                 Mov     Dx,Ax       ;
  200.                 Add     Si,Bx       ; Add this
  201.                 Call    Length      ; Get the length of second string
  202.                 Mov     Bp,Ax       ; Save length of new string for later
  203.                 Mov     Cx,Ax       ; Grab that length
  204.                 Inc     Cx          ; Include the null
  205.                 Rep     Movsb       ; Move it including the null
  206.                 Pop     Si          ; Get the offset back
  207.                                     ;
  208.                 Mov     BYTE PTR [Bx+Si],0  ; Make it null
  209.                                     ;
  210.                 Sub     Dx,Bp       ; Get difference
  211.                 Mov     Ax,Dx       ;
  212.                 Mov     Bx,Bp       ;
  213.                                     ;
  214.                 Pop     Bp          ;
  215.                 Pop     Di          ;
  216.                 Pop     Si          ;
  217.                 Pop     Dx          ;
  218.                 Pop     Cx          ;
  219.                 Ret                 ;
  220. Split           Endp
  221.  
  222.  
  223. LowerCase       Proc
  224. ;-----------------------------------------------------------------------------;
  225. ; Converts entire input string to lowercase.                                  ;
  226. ; INPUT :                                                                     ;
  227. ;    DS:SI = Address of source string.                                        ;
  228. ;    ES:DI = Address of new string exactly like first exept all lc.           ;
  229. ; OUTPUT :                                                                    ;
  230. ;    ES:DI = Address of New string all in lowercase.                          ;
  231. ;-----------------------------------------------------------------------------;
  232.                 Push    Ax          ;
  233.                 Push    Cx          ;
  234.                 Push    Si          ;
  235.                 Push    Di          ;
  236.                                     ;
  237.                 Cld                 ; Yep
  238.                 Call    Length      ; Get the Length
  239.                 Mov     Cx,Ax       ; Put it for the count
  240. _UtoLtop:       Lodsb               ; Get it
  241.                 Cmp     Al,'A'      ; Well
  242.                 Jb      @F          ; Nope
  243.                 Cmp     Al,'Z'      ; Well...
  244.                 Ja      @F          ; Nope skip add
  245.                 Add     Al,20h      ; Convert to lower case
  246. @@:             Stosb               ;
  247.                 Loop    _UtoLtop    ; Back
  248.                                     ;
  249.                 Pop     Di          ;
  250.                 Pop     Si          ;
  251.                 Pop     Cx          ;
  252.                 Pop     Ax          ;
  253.                 Ret                 ;
  254. LowerCase       Endp
  255.  
  256.  
  257. UpperCase       Proc
  258. ;-----------------------------------------------------------------------------;
  259. ; Converts entire input string to uppercase.                                  ;
  260. ; INPUT :                                                                     ;
  261. ;    DS:SI = Source string.                                                   ;
  262. ;    ES:DI = Address to place new string.                                     ;
  263. ; OUTPUT:                                                                     ;
  264. ;    ES:DI = address of new string like souce but all to uppercase.           ;
  265. ;-----------------------------------------------------------------------------;
  266.                 Push    Ax          ;
  267.                 Push    Si          ;
  268.                 Push    Di          ;
  269.                                     ;
  270.                 Cld                 ;
  271.                 Call    Length      ; Get the length
  272.                 Mov     Cx,Ax       ; For the count
  273. _LtoUtop:       Lodsb               ; Grab
  274.                 Cmp     Al,'a'      ; Well
  275.                 Jb      @F          ; Foreward
  276.                 Cmp     Al,'z'      ; Well,///
  277.                 Ja      @F          ; skip the subtract
  278.                 Sub     Al,20h      ; Take it out
  279. @@:             Stosb               ; Save it
  280.                 Loop    _LtoUtop    ; Hmm...
  281.                                     ;
  282.                 Pop     Di          ;
  283.                 Pop     Si          ;
  284.                 Pop     Ax          ;
  285.                 Ret                 ;
  286. UpperCase       Endp
  287.  
  288.  
  289.  
  290. Proper          Proc
  291. ;-----------------------------------------------------------------------------;
  292. ; Make a given input string to proper format. i. e.                           ;
  293. ;    "THIS IS A STRING",0     made proper would look like...                  ;
  294. ;    "This Is A String",0                                                     ;
  295. ; INPUT :                                                                     ;
  296. ;      DS:SI = Source input string.                                           ;
  297. ;      ES:DI = Destination address.                                           ;
  298. ; OUTPUT:                                                                     ;
  299. ;      ES:DI = address of output proper string.                               ;
  300. ;-----------------------------------------------------------------------------;
  301.                 Push    Ax          ;
  302.                 Push    Si          ;
  303.                 Push    Di          ;
  304.                                     ;
  305.                 Cld                 ;
  306.                                     ; First convert to lowercase
  307.                 Call    LowerCase   ; Make it all like lower case
  308.                                     ; Now search and do.
  309.                 Mov     Si,Di       ; Neww source address
  310.                 XchgSeg Ds,Es       ;
  311.                 Mov     Ah,0        ; Clear our flag
  312. _FindWord:      Lodsb               ;
  313.                 Cmp     Al,0        ; Are we done
  314.                 Je      _ProperDone ;
  315.                 Cmp     Al,'a'      ; well?
  316.                 Jb      @F          ;
  317.                 Cmp     Al,'z'      ;
  318.                 Ja      @F          ;
  319.                 Add     Al,-20h     ; Ok
  320.                 Dec     Ah          ;
  321. @@:             Stosb               ;
  322.                 Or      Ah,Ah       ;
  323.                 Jns     _FindWord   ; Not negative then keep finding
  324.                                     ; Found word and converted
  325. _FindDelim:     Lodsb               ; Grab
  326.                 Cmp     Al,0        ;
  327.                 Je      _ProperDone ;
  328.                 Cmp     Al,'a'      ; Well
  329.                 Jae     _Pt2xx      ;
  330.                 Jmp     SHORT   _DFp;
  331. _Pt2xx:         Cmp     Al,'z'      ; Ok?
  332.                 Jbe     @F          ; Skip the flag reset
  333. _DFp:           Inc     Ah          ; Back to 0
  334. @@:             Stosb               ;
  335.                 Or      Ah,Ah       ;
  336.                 Js      _FindDelim  ; While negative keep searching
  337.                 Jmp     _FindWord   ; Back to word search
  338. _ProperDone:    Stosb               ; Save the ASCIIZ
  339.                                     ;
  340.                 XchgSeg Ds,Es       ; Back to what these were
  341.                                     ;
  342.                 Pop     Di          ;
  343.                 Pop     Si          ;
  344.                 Pop     Ax          ;
  345.                 Ret                 ;
  346. Proper          Endp
  347.  
  348.  
  349. Trim            PROC
  350. ;-----------------------------------------------------------------------------;
  351. ; Trims an input string by removing all the leading and trailing spaces.      ;
  352. ; also leaves one space in between each word and if comma then it goes        ;
  353. ; the comma then space, if period then . and if not at end then 2 spaces      ;
  354. ; INPUT:                                                                      ;
  355. ;    DS:SI = address of string to be trimmed.                                 ;
  356. ;    ES:DI = destination of new string.                                       ;
  357. ; OUTPUT:                                                                     ;
  358. ;    AX = length of resulting new sentence and of course..                    ;
  359. ;    ES:DI = address of new string. NOTE THAT the original string is intact.  ;
  360. ;-----------------------------------------------------------------------------;
  361.                 Push    Cx          ;
  362.                 Push    Dx          ;
  363.                 Push    Si          ;
  364.                 Push    Di          ;
  365.                                     ;
  366.                 Cld                 ; Upper
  367.                 Call    Length      ; Get the length of the monstocity
  368.                 Mov     Cx,Ax       ; This is our count down counter
  369.                 Xor     Dx,Dx       ; This is our count up counter
  370.                 Mov     Ah,' '      ; Start the flag with a space
  371. _TrimTlop:      Jcxz    _TrimBlop   ; If we are done then exit
  372.                 Lodsb               ; Get a char
  373.                 Dec     Cx          ; Down one
  374.                 Cmp     Al,' '      ; Are we pointing to a space
  375.                 Jne     @F          ; Forweward
  376.                 Cmp     Ah,' '      ; If we find a space and we had a space
  377.                 Je      _TrimTlop   ; Then ignore it and we continue
  378.                 Cmp     Ah,'.'      ; But if we had a period
  379.                 Jne     _lastwaschar; ---
  380.                 Stosb               ; Store the space and
  381.                 Inc     Dx          ;
  382. _lastwaschar:   Stosb               ; Otherwise we store the space
  383.                 Xchg    Ah,Al       ; And switch the bytes
  384.                 Inc     Dx          ; Add one for our length
  385.                 Jmp     _TrimTlop   ; And back we go
  386. @@:             Cmp     Al,','      ; Are we pinting to a comma
  387.                 Jne     @F          ; Nope so we jump to next test
  388.                 Stosb               ; Save the comma
  389.                 Inc     Dx          ; Counter + 1
  390.                 Mov     Al,' '      ; and one space
  391.                 Stosb               ; After the comma
  392.                 Inc     Dx          ; Counter + 1
  393.                 Xchg    Ah,Al       ; Switch to tell our last thing
  394.                 Jmp     _TrimTlop   ; Back to do another
  395. @@:             Stosb               ; Save the char (period or otherwise)
  396.                 Inc     Dx          ; Hmm
  397.                 Xchg    Ah,Al       ; Specify the last char taken
  398.                 Jmp     _TrimTlop   ;
  399. _TrimBlop:      Mov     Al,0        ; Put a null here
  400.                 Stosb               ; Save the null
  401.                 Mov     TempW,Dx    ;
  402.                                     ;
  403.                 Pop     Di          ;
  404.                 Pop     Si          ;
  405.                 Pop     Dx          ;
  406.                 Pop     Cx          ;
  407.                 Mov     Ax,TempW    ; Get this
  408.                 Ret                 ;
  409. Trim            Endp
  410.  
  411.  
  412.  
  413. Checksum        Proc
  414. ;-----------------------------------------------------------------------------;
  415. ; Retruns the checksum of a string (including the asciiz -- as if )           ;
  416. ; INPUT :                                                                     ;
  417. ;         DS:SI = address of string                                           ;
  418. ; OUTPUT:                                                                     ;
  419. ;         AX = Word Checksum of string (by bytes) -- flags modified           ;
  420. ;-----------------------------------------------------------------------------;
  421.                 Push    Si          ; Save what we use
  422.                 Push    Bx          ;
  423.                 Push    Cx          ;
  424.                                     ;
  425.                 Call    Length      ; Get the length
  426.                 Mov     Cx,Ax       ; Put it here
  427.                 Xor     Bx,Bx       ;
  428.                 Xor     Ax,Ax       ; This too
  429. @@:             Add     Ax,[Bx+Si]  ; So add
  430.                 Inc     Bx          ; By one
  431.                 Loop    @B          ; Loop Baxk
  432.                                     ;
  433.                 Pop     Cx          ;
  434.                 Pop     Bx          ;
  435.                 Pop     Si          ;
  436.                 Test    Ax,Ax       ; Set the flags
  437.                 Ret                 ;
  438. Checksum        Endp
  439.  
  440.  
  441. Compare         Proc
  442. ;-----------------------------------------------------------------------------;
  443. ; Compares 2 input string and returns the compare result as follows...        ;
  444. ; If CF reset then the strings were exactly equal.                            ;
  445. ; Otherwise AX returns sevral values.. see below                              ;
  446. ; INPUT :                                                                     ;
  447. ;          DS:SI = Address of first string.                                   ;
  448. ;          ES:DI = Address of second string.                                  ;
  449. ; OUTPUT:                                                                     ;
  450. ;          If CF=0 AND AX = 0 Then the Strings are Identical.                 ;
  451. ;          If CF=0 AND AX > 0 Then Str2 = Str1 Upto(AX offset in Str1)...     ;
  452. ;                   LengthOfStr2 < LengthOfStr1.                              ;
  453. ;          IF CF=0 AND AX < 0 Then Str1 = Str2 (AX NegativeOffset in Str2)    ;
  454. ;                   LengthOfStr1 < LengthOfStr2.                              ;
  455. ;          Note above that strings are equal to a point and AX holds dif.     ;
  456. ;          If CF=1 AND AX > 0 Then Str1>Str2 and AX = Offset of Mismatch      ;
  457. ;          If CF=1 AND AX < 0 Then Str1<Str2 and AX = NegativeOffset Mismatch ;
  458. ; Just a note that Negative offset if the numerical negative of the offset    ;
  459. ; for that given number.  To find the actual offset, absolute value the num.  ;
  460. ;-----------------------------------------------------------------------------;
  461.                 Push    Bx          ;
  462.                 Push    Cx          ;
  463.                 Push    Si          ;
  464.                 Push    Di          ;
  465.                                     ;
  466.                 Call    Length      ; Get length of Number 1
  467.                 Xchg    Ax,Bx       ; Flip to save
  468.                 XchgSeg Ds,Es       ; Exchange the segments
  469.                 Call    Length      ; And get length of string 2
  470.                 XchgSeg Ds,Es       ; Switch them back
  471.                 Xchg    Ax,Bx       ; LENGTH1 in AX, LENGTH2 in BX
  472.                 Cmp     Ax,Bx       ; Check Ax vs. Bx
  473.                 Je      sameLength  ; The strings are the same length.
  474.                                     ;
  475.                                     ;
  476. sameLength:     Mov     TempW,Ax    ; Save the length that we got
  477.                 Mov     Cx,Ax       ; Put the count for the test here
  478.                 Clc                 ; Clear for fun!
  479.                 Repe    Cmpsb       ; Keep comparing the things
  480.                 Je      slEqual     ; Same length strings are equal
  481.                 Pushf               ; Save the flags
  482.                 Mov     Ax,TempW    ; Get that saved length
  483.                 Sub     Ax,Cx       ; Which char erred
  484.                 Dec     Ax          ; One more for the offset
  485.                 Popf                ; Get the flags to see WHICH is bigger
  486.                 Jnb     str1Bigger  ; If not below then 1 is bigger than 2
  487.                 Neg     Ax          ; Send back the negative offset
  488. str1Bigger:     Stc                 ; Set the carry
  489.                 Jmp short   compExit; Exit out of here
  490. slEqual:        Clc                 ; Clear the carry
  491.                 Xor     Ax,Ax       ; Clear AX
  492.                 Jmp short   compExit; Exit out of here
  493.                                     ;
  494.                                     ;
  495. compExit:       Mov     TempW,Ax    ; Save this
  496.                 Lahf                ; Save thew flags
  497.                 Mov     TempB,Ah    ; Put this here
  498.                 Pop     Di          ;
  499.                 Pop     Si          ;
  500.                 Pop     Cx          ;
  501.                 Pop     Bx          ;
  502.                 Mov     Ah,TempB    ; Get the flags
  503.                 Sahf                ; Set the flags
  504.                 Mov     Ax,TempW    ; Get AX Back
  505.                 Ret                 ; Say by bye
  506. Compare         Endp
  507.  
  508.                 END
  509.